package com.cqc.other.juc.producerConsumer.demo2;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 缓冲区容器类
 */
public class Container {
    /**
     * 缓冲区
     */
    private List<Integer> list = new LinkedList<>();
    /**
     * 阈值
     */
    private int capacity = 3;

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void add(Integer value) {
        boolean flag = false;
        try {
            flag = lock.tryLock(3, TimeUnit.SECONDS);
            //1如果 缓冲区数量 大于 阈值，则生产者等待
            if (list.size() >= capacity) {
                System.out.println("缓冲区已满，生产者进入等待状态，" + Thread.currentThread().getName());
                //进入等待状态
                condition.await();
            }
            //2把数据加入缓冲区
            list.add(value);
            System.out.println("生产者，value:" + value + "，" + Thread.currentThread().getName());
            //3唤醒 消费者和生产者
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (flag) {
                lock.unlock();
            }
        }
    }

    public void get() {
        boolean flag = false;
        try {
            flag = lock.tryLock(3, TimeUnit.SECONDS);
            //如果缓冲区没有数据，则消费者进入等待状态
            if (list.isEmpty()) {
                System.out.println("缓冲区无数据，消费者进入等待状态，" + Thread.currentThread().getName());
                condition.await();
            }
            //如有有数据，则取出该数据，并删除
            Integer value = list.remove(0);
            System.out.println("消费者，value:" + value + "，" + Thread.currentThread().getName());
            //唤醒 生产者和消费者
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (flag) {
                lock.unlock();
            }
        }
    }
}
